package com.example.speeddating.utils;


import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;

import java.util.Date;
import java.util.Map;

/**
 * JwtToken 工具类
 */
public class JwtTokenUtil {


    /**
     * 从数据声明生成令牌
     *
     * @param claims 数据声明
     * @return 令牌
     */
    public static String createToken(Map<String, Object> claims) {
        String token = Jwts.builder()
                .setClaims(claims)//把荷载存储到里面
                .setExpiration(generateExpirationDate())//设置失效时间
                .signWith(Keys.hmacShaKeyFor(Decoders.BASE64.decode(JwtConstant.JWT_SECRET))) //签名
                .compact();
        return token;
    }
    /**
     * 从令牌中获取数据声明
     *
     * @param token 令牌
     * @return 数据声明
     */
    public static Claims parseToken(String token){
        Claims claims=null;
        try{
            claims = Jwts.parserBuilder()
                    .setSigningKey((Decoders.BASE64.decode(JwtConstant.JWT_SECRET)))
                    .build()
                    .parseClaimsJws(token)
                    .getBody();
        }catch (Exception e){
            e.printStackTrace();
        }
        return claims;
    }

    /**
     * 生成token失效时间
     */
    private static Date generateExpirationDate() {
        //失效时间是当前系统的时间+我们在配置文件里定义的时间
        return new Date(System.currentTimeMillis()+JwtConstant.JWT_EXPIRATION);
    }
    public static String getUserIdByToken(String token){
        Claims claims = parseToken(token);
        return getValue(claims, JwtConstant.USER_INFO_ID);
    }

    /**
     * 根据token获取用户名
     */
    public static String getUserName(String token){
        Claims claims = parseToken(token);
        return getValue(claims, JwtConstant.USER_INFO_USERNAME);
    }

    /**
     * 验证token是否有效
     */
    public static boolean validateToken(String token){
        //claims 为null 意味着要门jwt被修改
        Claims claims = parseToken(token);
        System.out.println(claims);
        return claims != null &&!isTokenExpired(token);
    }

    /**
     * 判断token是否已经失效
     * @param token
     * @return
     */
    public static boolean isTokenExpired(String token) {
        //先获取之前设置的token的失效时间
        Date expireDate=getExpiredDate(token);
        return expireDate.before(new Date()); //判断下，当前时间是都已经在expireDate之后
    }

    /**
     * 根据token获取失效时间
     * 也是先从token中获取荷载
     * 然后从荷载中拿到到设置的失效时间
     * @param token
     * @return
     */
    private static Date getExpiredDate(String token) {
        Claims claims=parseToken(token);
        return claims.getExpiration();
    }

    /**
     * 刷新我们的token：重新构建jwt
     */
    public static String refreshToken(String token){
        Claims claims=parseToken(token);
        claims.put(JwtConstant.JWT_CREATE_TIME,new Date());
        return createToken(claims);
    }

    /**
     * 根据身份信息获取键值
     *
     * @param claims 身份信息
     * @param key 键
     * @return 值
     */
    public static String getValue(Claims claims, String key){
        return claims.get(key) != null ? claims.get(key).toString():null;
    }
}